package org.oy.sealogger.logger;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Vector;

import org.oy.sealogger.route.GPSLocation;
import org.oy.sealogger.route.Route;
import org.oy.sealogger.route.WaypointData;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;


/**
 * @author juho
 *
 */
public class XMLLogReader extends DefaultHandler {

	private XMLReader parser = null;
	private Vector<GPSLocation> path = null;
	
	private StringBuffer buffer = null;
	private GPSLocation currentLoc = null;
	
	public Route readFile(String filename) throws IOException, SAXException {
		path = null;
		try {
			parser = XMLReaderFactory.createXMLReader();
		} catch (SAXException se) {
			System.out.println(se);
		}
		
		if (checkFile(filename)) {
			parser.setContentHandler(this);
			parser.parse(filename);

		}
		if (path == null) {
			return null;
		} else if (path.size() == 0) {
			return null;
		} else {
			return new Route(filename, path, false);
		}	
	}
	
	public boolean checkFile(String filename) {
		boolean success = false;
		
		try {
			parser.parse(filename);
			success = true;
		} catch (SAXParseException spe) {
			System.out.println(spe);
			// DEBUG
			StringBuffer sb = new StringBuffer( spe.toString() );
	        sb.append("\n  Line number: " + spe.getLineNumber());
	        sb.append("\nColumn number: " + spe.getColumnNumber() );
	        sb.append("\n Public ID: " + spe.getPublicId() );
	        sb.append("\n System ID: " + spe.getSystemId() + "\n");
	        System.out.println( sb.toString() );
		        
			System.out.println("Adding end tag to see if it fixes the file");
			try {
				BufferedWriter out = new BufferedWriter(new FileWriter(filename, true));
				out.write("</"+XMLTags.DOCUMENT_TAG+">");
				out.close();
				// try again
				parser.parse(filename);
				success = true;
			} catch (IOException ioe) {
				System.out.println(ioe);
			} catch (SAXException se) {
				System.out.println(se);
			}
		} catch (SAXException se) {
			System.out.println(se);
		} catch (IOException ioe) {
			System.out.println(ioe);
		}
		
		if (!success) {
			System.out.println("File is not well formed xml");
		} else {
			System.out.println("Success!");
		}
		
		return success;
	}
	
	// handler callbacks
	
	public void startDocument() {
		path = new Vector<GPSLocation>(200);
	}
	
	public void startElement(String namespaceURI, String localname, String qualifiedName, Attributes atts) {
		
		if (qualifiedName.equals(XMLTags.LOCATION_TAG)){
			currentLoc = new GPSLocation();
		} else if (qualifiedName.equals(XMLTags.WAYPOINT_TAG)) {
			currentLoc = new WaypointData();
		} else if (qualifiedName.equals(XMLTags.LATITUDE_TAG) || qualifiedName.equals(XMLTags.LONGITUDE_TAG)) {
			buffer = new StringBuffer();
		}
	}
	
	public void endElement(String namespaceURI, String localName, String qualifiedName) {
		
		if (qualifiedName.equals(XMLTags.LONGITUDE_TAG)) {
			currentLoc.setLongitude(Double.valueOf(buffer.toString()));
			buffer = null;
		} else if (qualifiedName.equals(XMLTags.LATITUDE_TAG)) {
			currentLoc.setLatitude(Double.valueOf(buffer.toString()));
			buffer = null;
		} else if (qualifiedName.equals(XMLTags.COMMENT_TAG)) {
			if (buffer != null) {
				((WaypointData)currentLoc).setComment(buffer.toString());
			}
			buffer = null;
		} else if (qualifiedName.equals(XMLTags.IMAGE_TAG)) {
			if (buffer != null) {
				((WaypointData)currentLoc).setImage(buffer.toString());
			} 
			buffer = null;
		}  else if (qualifiedName.equals(XMLTags.LOCATION_TAG) || qualifiedName.equals(XMLTags.WAYPOINT_TAG)) {
			path.add(currentLoc);
			buffer = null;
		}
	}
	
	public void characters(char[] text, int start, int length) throws SAXException {
		if (buffer != null) {
			buffer.append(text, start, length);
		}
	}
	
	// testing purposes
	public static void main(String[] args) {
		XMLLogReader reader = new XMLLogReader();
		long start = System.currentTimeMillis();
		Route route = null;
		try {
			route = reader.readFile("test2.xml");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		if (route != null) {
			System.out.println((System.currentTimeMillis() - start) + "ms" + " location olioita tehtiin: " + route.getPath().size() 
					+ " joka on n. " + route.getPath().size() / 1800 + " tunnin edestä logia");

		}

	}
}
